package com.iceberg.action.database;

import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.gson.Gson;
import com.iceberg.model.customer.Customer;
import com.iceberg.model.database.Column;
import com.iceberg.model.database.Table;
import com.iceberg.model.database.TableData;
import com.iceberg.model.jqgrid.JqGridTable;
import com.iceberg.service.database.DatabaseService;
import com.opensymphony.xwork2.ActionContext;

public class DatabaseAction {

  DatabaseService databaseService = null;
  JqGridTable jqGridTable = new JqGridTable();
  String tableName = "";
  String schemaName = "";

  public JqGridTable getJqGridTable() {
    return jqGridTable;
  }

  public void setJqGridTable(JqGridTable jqGridTable) {
    this.jqGridTable = jqGridTable;
  }

 

  private InputStream inputStream;
  

  public void setInputStream(InputStream inputStream) {
    this.inputStream = inputStream;
  }

  public InputStream getInputStream() {
    return inputStream;
   }
  
 
  
  public String getSchemaName() {
    return schemaName;
  }

  public void setSchemaName(String schemaName) {
    this.schemaName = schemaName;
  }

  public String getTableName() {
    return tableName;
  }

  public void setTableName(String tableName) {
    this.tableName = tableName;
  }

  

 
  public String index() throws Exception {
    //1. set user principal
    //2. init user menu
    return "index";
  }

  public String list() throws Exception {
    //1. set user principal
    //2. init user menu
   
   initiateMetadata();
    
   // this.colNames = "[\"CUSTOMER_ID\",\"customer_name\",\"address\",\"created_date\"]";
   // this.colModel = "[{\"index\":\"CUSTOMER_ID\",\"align\":\"left\",\"width\":\"100\",\"name\":\"CUSTOMER_ID\",editable:true},{\"index\":\"customer_name\",\"align\":\"left\",\"width\":\"100\",\"name\":\"customer_name\",editable:true},{\"index\":\"address\",\"align\":\"left\",\"width\":\"100\",\"name\":\"address\",editable:true},{\"index\":\"created_date\",\"align\":\"left\",\"width\":\"100\",\"name\":\"created_date\",editable:true}]";
    String test = "";
    return "list";
  }
  public String dataUpdate() throws Exception {
    //1. set user principal
    //2. init user menu
    //get the new attributes
    //get the table name
    //get the table row data
    //save data
    Map<String, Object> parameters = ActionContext.getContext().getParameters();
    
    boolean isSucceed = databaseService.dataUpdate(tableName, parameters);
    
    inputStream = new StringBufferInputStream(
        "Succeed update the data!");
    String test = "";
    return "succeed";
  }
  public String dataOperation() throws Exception {

    String oper = this.jqGridTable.getOperation();
    if(oper != null) {
      if("del".equals(oper)) {
        return dataDelete();
      }
      else if("edit".equals(oper)) {
        return dataUpdate();
      }
      else if("add".equals(oper)) {
        return dataCreate();
      }
      else {
        return "failed";
      }
    }
    else {
      return "failed";
    }
  }
  public String dataCreate() throws Exception {
    //1. set user principal
    //2. init user menu
    Map<String, Object> parameters = ActionContext.getContext().getParameters();
    
    this.databaseService.dataCreate(tableName, parameters);

    inputStream = new StringBufferInputStream(
        "Hello World! This is a text string response from a Struts 2 Action.");
    String test = "";
    return "succeed";
  }
  public String dataDelete() throws Exception {
    //1. set user principal
    //2. init user menu
    
   Map<String, Object> parameters = ActionContext.getContext().getParameters();
    
    this.databaseService.dataDelete(tableName, parameters);

    inputStream = new StringBufferInputStream(
        "Hello World! This is a text string response from a Struts 2 Action.");
    String test = "";
    return "succeed";
  }
  

  private void initiateMetadata() {
    Table table= this.databaseService.getTable(null, null, tableName);
    List<Column> columns = table.getColumnList();
    Column pkColumn = table.getPrimaryKeyColumn();
    //3. set colNames and colModel
    List<String> colNameList = new ArrayList<String>();
    List<HashMap<String,String>> colModelMap = new ArrayList<HashMap<String, String>>();
    
    for(Column column:columns) {
      colNameList.add(column.getColumnName());
      //"[ 'customerId', 'address', 'name', 'createdDate']"
      HashMap<String, String> columnMap = new HashMap<String,String>();
      columnMap.put("name", column.getColumnName());
      columnMap.put("index", column.getColumnName());
      columnMap.put("width", "" + 100);
      columnMap.put("align", "left");
      columnMap.put("editable", "true");
      if(column.getColumnName().equals(pkColumn.getColumnName())) {
        columnMap.put("key", "true");
      }
      colModelMap.add(columnMap);
    }
    Gson gson = new Gson();
    jqGridTable.setColNames(gson.toJson(colNameList));   
    String colModel = gson.toJson(colModelMap);
    colModel = removeKeyQuotes(colModel);
    colModel = colModel.replaceAll("\"true\"", "true");
    jqGridTable.setColModel(colModel);
    
   
  }
  public String removeKeyQuotes(String original) {
    Pattern replace = Pattern.compile("\"[^\"]*\"\\s?:");
    Matcher matcher = replace.matcher(original);
    StringBuffer sb = new StringBuffer();
    while (matcher.find()) {
      String value = matcher.group(0);
      value=value.replace("\"", "");
      matcher.appendReplacement(sb, value);
    }
    matcher.appendTail(sb);
    return sb.toString();
  }
  public String dataLoad() throws Exception {
    //1. set user principal
    //2. init user menu
    String tbName = this.tableName;
    //getSimulateData();
    this.databaseService.getTableData(tableName, jqGridTable);
    return "load";
  }

  private void getSimulateData() {
    for (int i = 0; i < 10; i++) {
      Customer c = new Customer();
      c.setCustomerId(new Long(i));
      c.setAddress("address" + i);
      c.setName("name" + i);
      c.setCreatedDate(new Date());
      //tableData.add(c);
    }
  }

  public DatabaseService getDatabaseService() {
    return databaseService;
  }

  public void setDatabaseService(DatabaseService databaseService) {
    this.databaseService = databaseService;
  }

}
